package list;

/**
 * @version 1.0
 * 功能目的描述 ：用于     实现双向链表    ========>>>>>>>>>>>
 * @author： pang-yun
 * @date： 2021-07-21 13:39
 */

public class DoubleLinkedLIstDemo {
    public static void main(String[] args) {

        DoubleNode node1 = new DoubleNode(1, "A", "a");
        DoubleNode node2 = new DoubleNode(2, "B", "b");
        DoubleNode node3 = new DoubleNode(3, "C", "c");
        DoubleNode node4 = new DoubleNode(4, "D", "d");

        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.add(node1);
        doubleLinkedList.add(node2);
        doubleLinkedList.add(node3);
        doubleLinkedList.add(node4);
        doubleLinkedList.list();
        System.out.println("------update---------");
        DoubleNode node5 = new DoubleNode(4, "update", "test");
        doubleLinkedList.update(node5);
        doubleLinkedList.list();
        System.out.println("-----delete--------");
        doubleLinkedList.delete(node5);
        doubleLinkedList.list();

    }
}


//双向链表的节点
class DoubleNode {
    public Integer number;
    public String name;
    public String nickName;
    public DoubleNode next;  //指向下一个节点 , 默认为null
    public DoubleNode pre;    // 指向 上一个节点  默认为 null

    public DoubleNode(Integer number, String name, String nickName) {
        this.number = number;
        this.name = name;
        this.nickName = nickName;

    }

    @Override
    public String toString() {
        return "DoubleNode{" +
                "number=" + number +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}


//实现双向链表
class DoubleLinkedList {
    //初始化头结点
    DoubleNode head = new DoubleNode(0, "", "");

    //返回双向链表的头节点
    public DoubleNode getHead() {
        return head;
    }

    //遍历双向链表的方法
    public void list() {
        if (head.next == null) {
            System.out.println("list为空");
            return;
        }
        // 创建辅助节点 遍历
        DoubleNode temp = head.next;
        while (true) {
            //如果已经到最后 退出
            if (temp == null) {
                break;
            }
            System.out.println(temp.toString());
            temp = temp.next;
        }
    }


    //------------------------------添加到链表的最后--------------------
    /*使用辅助变量 ，遍历到最后 将node放上去*/
    public void add(DoubleNode node) {

        DoubleNode temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }

            temp = temp.next;
        }
        temp.next = node;
        node.pre = temp;

    }

    //--------------------------修改双向链表------------------
    /*1. 判断 list是否为空
     * 2. 创建变量temp   以及是否找到的标志flag
     * 3.  在找到或者遍历完的情况下退出
     * 4.  退出后 如果 flag为真 将temp的 相关内容进行修改*/

    public void update(DoubleNode node) {
        DoubleNode temp = head;
        if (temp.next == null) {
            System.out.println("list为空");
            return;
        }
        boolean flag = false;

        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.number == node.number) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.name = node.name;
            temp.nickName = node.nickName;
            //----------------------不要让 pre   next  也等于新修改的node   因为它们都是空的
        } else {
            System.out.println("没有相应的node");
        }

    }


    //删除双向链表，可以实现自我删除 ， 因为有 pre   不再需要辅助指针
    public void delete(DoubleNode node) {
        DoubleNode temp = head.next;
        if (head.next == null) {
            System.out.println("list为空");
            return;
        }
        boolean flag = false;
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.number == node.number) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            // 删除节点的 上一个的next   变成 删除节点的下一个
            temp.pre.next = temp.next;


            // temp.next.pre = temp.pre; 这种写法 删除最后一个节点时 会出现空指针异常  只有在下一个不是null的时候才可以这样写
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.println("没有此节点");
        }
    }

}
